/**
 * Copyright © 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.cms.content.service;

import com.jeeplus.cms.util.CmsCacheUtils;
import com.jeeplus.cms.util.CmsUtils;
import com.jeeplus.core.persistence.Page;
import com.jeeplus.core.service.CrudService;
import com.jeeplus.modules.cms.column.entity.CmsColumn;
import com.jeeplus.modules.cms.content.entity.CmsContents;
import com.jeeplus.modules.cms.content.mapper.CmsContentsMapper;
import com.jeeplus.modules.cms.contenttype.entity.CmsContentType;
import com.jeeplus.modules.cms.site.entity.CmsSite;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 发布内容表Service
 *
 * @author Sawyer
 * @version 2020-11-22
 */
@Service
@Transactional(readOnly = true)
public class CmsContentsService extends CrudService<CmsContentsMapper, CmsContents> {

    @Override
    public CmsContents get(String id) {
        return super.get(id);
    }

    @Override
    public List<CmsContents> findList(CmsContents cmsContents) {
        return super.findList(cmsContents);
    }

    @Override
    public List<CmsContents> findAllList(CmsContents entity) {
        return findList(entity);
    }

    @Override
    public Page<CmsContents> findPage(Page<CmsContents> page, CmsContents cmsContents) {
        Page<CmsContents> contentsPage = super.findPage(page, cmsContents);
        contentsPage.getList().forEach(content -> {
            CmsColumn column = CmsUtils.getColumnById(content.getColumnId());
            CmsContentType contentType = CmsUtils.getContentTypeById(content.getContentTypeId());
            content.setColumnName(null == column ? "" : column.getName());
            content.setContentTypeName(null == contentType ? "" : contentType.getName());
        });
        return contentsPage;
    }

    @Override
    @Transactional(readOnly = false)
    public void save(CmsContents cmsContents) {
        // 设置siteId
        String siteId = "";
        if (StringUtils.isNotBlank(cmsContents.getColumnId())) {
            CmsColumn cmsColumn = CmsUtils.getColumnById(cmsContents.getColumnId());
            siteId = null != cmsColumn ? cmsColumn.getSiteId() : null;
            cmsContents.setSiteId(siteId);
        }

        // 新增记录时初始化数据
        if (StringUtils.isBlank(cmsContents.getId())) {
            cmsContents.init();
        }

        super.save(cmsContents);

        // 清除缓存
        CmsCacheUtils.removeCacheBySiteId(CmsCacheUtils.CONTENT_LIST_CACHE, siteId);
    }

    @Override
    @Transactional(readOnly = false)
    public void delete(CmsContents cmsContents) {
        String siteId = get(cmsContents.getId()).getSiteId();
        super.delete(cmsContents);

        // 清除缓存
        CmsCacheUtils.removeCacheBySiteId(CmsCacheUtils.CONTENT_LIST_CACHE, siteId);
    }

    /**
     * 更新过期置顶权重
     * <p>
     * 生产时可直接设置定时任务调用此服务
     * </p>
     *
     * @see
     */
    @Transactional(readOnly = false)
    public void updateExpiredWeight() {
        mapper.updateExpiredWeight(new CmsContents());
    }

    /**
     * 前端有请求时定期更新过期置顶权重
     */
    @Transactional(readOnly = false)
    public void updateExpiredWeightToReq() {
        //更新过期权重，间隔1小时
        Date updateExpiredWeightTime = (Date) CmsCacheUtils.getCache(CmsUtils.UPDATE_EXPIRED_WEIGHT_TIME_CACHE);
        if (updateExpiredWeightTime == null || (updateExpiredWeightTime.getTime() < System.currentTimeMillis())) {
            updateExpiredWeight();
            CmsCacheUtils.putCache(CmsUtils.UPDATE_EXPIRED_WEIGHT_TIME_CACHE, DateUtils.addHours(new Date(), 1));
        }
    }

    @Transactional(readOnly = false)
    public void updateHitsAddOne(String id) {
        mapper.updateHitsAddOne(id);

        for (CmsSite site : CmsCacheUtils.getSiteListByCache()) {
            Optional<CmsContents> optional = CmsCacheUtils.getContentListByCache(site.getId(), false)
                    .stream()
                    .filter(item -> id.equals(item.getId()))
                    .findFirst();

            if (optional.isPresent()) {
                optional.get().setHits(null == optional.get().getHits() ? 1 : optional.get().getHits() + 1);
                break;
            }
        }
    }

    public Integer getTotalHitsBySiteId(String siteId) {
        return mapper.getTotalHitsBySiteId(siteId);
    }
}
